﻿using System;
using System.IO;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using CivilRegistry.Common;
using CivilRegistry.ControlledModel;

namespace CivilRegistry
{
    public partial class VoterCard : System.Web.UI.Page
    {
        Admin loggedInAdmin = null;
        Person loggedInPerson = null;
        bool isApproved;
        bool isDeactivated;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (SessionHandler.CurrentSession.User == null)
            {
                Response.Redirect("~/Login.aspx?&redirect=VoterCard.aspx");
            }

            SiteMaster masterPage = (SiteMaster)Page.Master;
            masterPage.SelectedMenu = "VoterCard";

            lblStatus.Text = "";

            if (SessionHandler.CurrentSession.User is Admin)
            {
                this.loggedInAdmin = (Admin)SessionHandler.CurrentSession.User;
            }
            else if (SessionHandler.CurrentSession.User is Person)
            {
                this.loggedInPerson = (Person)SessionHandler.CurrentSession.User;
            }
            else
            {
                Response.Redirect("~/Default.aspx");
            }
            

            if (!Page.IsPostBack)
            {
                if (SessionHandler.CurrentSession.User is Admin)
                {
                    pnlDisplay.Visible = false;
                    pnlAdmin.Visible = true;
                }
                else
                {
                    this.LoadVoterCardValues(ControlledModel.VoterCard.FindByPerson(this.loggedInPerson));
                    pnlAdmin.Visible = false;
                }
            }
        }

        private void FillVoterCardGrid()
        {
            this.FillVoterCardGrid("VoterCardId", SortDirection.Ascending);
        }

        private void FillVoterCardGrid(string columnName, SortDirection sortDirection)
        {
            int pageIndex = gvVoterCard.PageIndex;
            if (pnlFilter.Visible)
            {
                gvVoterCard.DataSource = (from voterCard in this.loggedInAdmin.GetVoterCardsBy(cblFilter.Items[0].Selected, cblFilter.Items[1].Selected)
                                          select new
                                          {
                                              VoterCardId = voterCard.VoterCardId,
                                              VoterId = voterCard.VoterId,
                                              FirshtName = voterCard.Person.FirstName,
                                              MiddleName = voterCard.Person.MiddleName,
                                              LastName = voterCard.Person.LastName,
                                              IsApproved = voterCard.IsApproved
                                          }).OrderBy(columnName, sortDirection);
            }
            else
            {
                gvVoterCard.DataSource = (from voterCard in this.loggedInAdmin.GetVoterCardsForApproval()
                                          select new
                                          {
                                              VoterCardId = voterCard.VoterCardId,
                                              VoterId = voterCard.VoterId,
                                              FirshtName = voterCard.Person.FirstName,
                                              MiddleName = voterCard.Person.MiddleName,
                                              LastName = voterCard.Person.LastName,
                                              IsApproved = voterCard.IsApproved
                                          }).OrderBy(columnName, sortDirection);
            }
            gvVoterCard.DataBind();
            gvVoterCard.PageIndex = pageIndex;
        }

        protected void gvVoterCard_Sorting(object sender, GridViewSortEventArgs e)
        {
            if (SessionHandler.CurrentSession.SortDirection == SortDirection.Descending)
            {
                SessionHandler.CurrentSession.SortDirection = SortDirection.Ascending;
            }
            else
            {
                SessionHandler.CurrentSession.SortDirection = SortDirection.Descending;
            }

            this.FillVoterCardGrid(e.SortExpression, SessionHandler.CurrentSession.SortDirection);
        }

        protected void gvVoterCard_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            gvVoterCard.PageIndex = e.NewPageIndex;
            this.FillVoterCardGrid();
        }

        protected void gvVoterCard_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "Edit")
            {
                var hdnVoterCardId = (HiddenField)gvVoterCard.Rows[Convert.ToInt32(e.CommandArgument) - (gvVoterCard.PageSize * gvVoterCard.PageIndex)].FindControl("hdnVoterCardId");

                this.LoadVoterCardValues(ControlledModel.VoterCard.FindById(Convert.ToInt32(hdnVoterCardId.Value)));

                gvVoterCard.Visible = false;
                pnlFilter.Visible = false;
                btnApply.Visible = false;
                pnlTools.Visible = false;
                pnlDisplay.Visible = true;
                pnlAdminActions.Visible = true;

                if (this.isApproved)
                {
                    btnApprove.Visible = false;
                    btnDeny.Visible = false;
                    btnDeactivate.Visible = true;
                    if (this.isDeactivated)
                    {
                        btnDeactivate.Text = "Re-Activate";
                    }
                    else
                    {
                        btnDeactivate.Text = "Deactivate";
                    }
                }
                else
                {
                    btnApprove.Visible = true;
                    btnDeny.Visible = true;
                    btnDeactivate.Visible = false;
                }
            }
        }

        protected void gvVoterCard_RowEditing(object sender, GridViewEditEventArgs e)
        {
            e.Cancel = true;
        }

        protected void cblFilter_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.FillVoterCardGrid();
        }

        protected void btnViewAll_Click(object sender, EventArgs e)
        {
            gvVoterCard.Visible = true;
            pnlFilter.Visible = true;
            pnlTools.Visible = false;
            pnlDisplay.Visible = false;
            pnlAdminActions.Visible = false;

            this.FillVoterCardGrid();
        }

        protected void btnViewVoterCardRequest_Click(object sender, EventArgs e)
        {
            pnlTools.Visible = false;
            gvVoterCard.Visible = true;
            pnlDisplay.Visible = false;
            pnlAdminActions.Visible = false;

            this.FillVoterCardGrid();
        }

        protected void btnApply_Click(object sender, EventArgs e)
        {
            btnApply.Visible = false;
            pnlDisplay.Visible = false;
            pnlVoterCardRequest.Visible = true;
            this.LoadEditAddressValues(this.loggedInPerson);
        }

        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            if (((TextBox)ucPermanentAddress.FindControl("txtAddress")).Text != "")
            {
                PermanentAddress permanentAddress = this.loggedInPerson.PermanentAddress ?? new PermanentAddress();

                permanentAddress.Address = ((TextBox)ucPermanentAddress.FindControl("txtAddress")).Text;
                permanentAddress.PIN = (Convert.ToInt32(((TextBox)ucPermanentAddress.FindControl("txtPIN")).Text));
                permanentAddress.District = District.FindById(Convert.ToInt32(((DropDownList)ucPermanentAddress.FindControl("ddlDistrictName")).SelectedValue));
                permanentAddress.District.State = State.FindById(Convert.ToInt32(((DropDownList)ucPermanentAddress.FindControl("ddlStateName")).SelectedValue));
                permanentAddress.City = ((TextBox)ucPermanentAddress.FindControl("txtCity")).Text;

                this.loggedInPerson.PermanentAddress = permanentAddress;
            }

            if (((TextBox)ucPresentAddress.FindControl("txtAddress")).Text != "")
            {
                PresentAddress presentAddress = this.loggedInPerson.PresentAddress ?? new PresentAddress();

                presentAddress.Address = ((TextBox)ucPresentAddress.FindControl("txtAddress")).Text;
                presentAddress.PIN = (Convert.ToInt32(((TextBox)ucPresentAddress.FindControl("txtPIN")).Text));
                presentAddress.District = District.FindById(Convert.ToInt32(((DropDownList)ucPresentAddress.FindControl("ddlDistrictName")).SelectedValue));
                presentAddress.District.State = State.FindById(Convert.ToInt32(((DropDownList)ucPresentAddress.FindControl("ddlStateName")).SelectedValue));
                presentAddress.City = ((TextBox)ucPresentAddress.FindControl("txtCity")).Text;

                this.loggedInPerson.PresentAddress = presentAddress;
            }

            FileUpload electricityBillUploader = ((FileUpload)ucPermanentAddress.FindControl("FlupldElectricitybill"));
            if (electricityBillUploader.PostedFile.FileName != "")
            {
                if (electricityBillUploader.PostedFile.FileName.ToLowerInvariant().EndsWith(".pdf"))
                {
                    electricityBillUploader.SaveAs((this.loggedInPerson).GetPermanentAddressElectricalBillFilePath());
                }
                else
                {
                    lblStatus.Text = "Please upload a valid file. Note: The file should be in pdf format.";
                    return;
                }
            }

            electricityBillUploader = ((FileUpload)ucPresentAddress.FindControl("FlupldElectricitybill"));
            if (electricityBillUploader.PostedFile.FileName != "")
            {
                if (electricityBillUploader.PostedFile.FileName.ToLowerInvariant().EndsWith(".pdf"))
                {
                    electricityBillUploader.SaveAs((this.loggedInPerson).GetPresentAddressElectricalBillFilePath());
                }
                else
                {
                    lblStatus.Text = "Please upload a valid file. Note: The file should be in pdf format.";
                    return;
                }
            }

            ControlledModel.VoterCard voterCard = new ControlledModel.VoterCard();

            voterCard.Person = this.loggedInPerson;
            voterCard.VoterId = "Not-Assigned-" + voterCard.VoterCardId;

            try
            {
                this.loggedInPerson.ApplyForVoterCard(voterCard);
            }
            catch (ApplicationException ex)
            {
                lblStatus.Text = ex.Message;
                return;
            }
            catch (Exception ex)
            {
                Logger.ErrorLogger.Log(ex);
                lblStatus.Text = "An unexpected error occured on the application. Please contact the appropriate technical candidate for more information.";
                return;
            }

            lblStatus.Text = "Application sent successfully.";

            EmailHelper.SendApplicationRequestNotification("VoterCard", this.loggedInPerson, ref lblStatus);
            SMSHelper.SendApplicationRequestNotification("VoterCard", this.loggedInPerson, ref lblStatus);

            pnlVoterCardRequest.Visible = false;
        }

        private void LoadEditAddressValues(ControlledModel.User user)
        {
            ((TextBox)ucPermanentAddress.FindControl("txtAddress")).Text = user.PermanentAddress.Address;
            ((TextBox)ucPermanentAddress.FindControl("txtPIN")).Text = user.PermanentAddress.PIN.ToString();
            ((DropDownList)ucPermanentAddress.FindControl("ddlStateName")).SelectedIndex = user.PermanentAddress.District.State.StateId;
            var ddlDistrictName = ((DropDownList)ucPermanentAddress.FindControl("ddlDistrictName"));
            ddlDistrictName.DataSource = District.FindAllByStateId(user.PermanentAddress.District.State.StateId);
            ddlDistrictName.DataBind();
            ddlDistrictName.SelectedValue = user.PermanentAddress.District.DistrictId.ToString();
            ((TextBox)ucPermanentAddress.FindControl("txtCity")).Text = user.PermanentAddress.City;

            if (user.PresentAddress != null)
            {
                ((TextBox)ucPresentAddress.FindControl("txtAddress")).Text = user.PresentAddress.Address;
                ((TextBox)ucPresentAddress.FindControl("txtPIN")).Text = user.PresentAddress.PIN.ToString();
                ((DropDownList)ucPresentAddress.FindControl("ddlStateName")).SelectedIndex = user.PresentAddress.District.State.StateId;
                ddlDistrictName = ((DropDownList)ucPresentAddress.FindControl("ddlDistrictName"));
                ddlDistrictName.DataSource = District.FindAllByStateId(user.PresentAddress.District.State.StateId);
                ddlDistrictName.DataBind();
                ddlDistrictName.SelectedValue = user.PresentAddress.District.DistrictId.ToString();
                ((TextBox)ucPresentAddress.FindControl("txtCity")).Text = user.PresentAddress.City;
            }
        }

        protected void LoadVoterCardValues(ControlledModel.VoterCard voterCard)
        {
            if (voterCard != null)
            {
                this.isApproved = voterCard.IsApproved != null ? voterCard.IsApproved.Value : false;
                this.isDeactivated = voterCard.DeactivateReason == null ? false : true;
                btnApply.Visible = false;
                lblVoterIdValue.Text = voterCard.VoterId.StartsWith("Not-Assigned") ? "Yet to Approve" : voterCard.VoterId;
                hdnVoterCardId.Value = voterCard.VoterCardId.ToString();
                lblFirstNameValue.Text = voterCard.Person.FirstName;
                lblMiddleNameValue.Text = voterCard.Person.MiddleName;
                lblLastNameValue.Text = voterCard.Person.LastName;

                if (voterCard.Person.Gender == "M")
                {
                    lblSexValue.Text = "Male";
                }
                else if (voterCard.Person.Gender == "F")
                {
                    lblSexValue.Text = "Female";
                }

                lblDateofBirthValue.Text = voterCard.Person.DateOfBirth.ToString();

                lblAgeValue.Text = voterCard.Person.Age.ToString();
                lblAddressValue.Text = voterCard.Person.PermanentAddress.Address;
                lblPINValue.Text = voterCard.Person.PermanentAddress.PIN.ToString();
                lblCityValue.Text = voterCard.Person.PermanentAddress.City;
                lblStateNameValue.Text = voterCard.Person.PermanentAddress.District.State.StateName;
                lblDistrictNameValue.Text = voterCard.Person.PermanentAddress.District.DistrictName;

                if (!File.Exists(voterCard.Person.GetPermanentAddressElectricalBillFilePath()))
                {
                    lbnViewElectricBillXerox.Visible = false;
                }
                else
                {
                    lbnViewElectricBillXerox.Visible = true;
                }
            }
            else
            {
                lblStatus.Text = "No VoterCard found for you account. Please contact the relavant office for more information."
                    + " If you dont have the one, please apply for it.";
                pnlDisplay.Visible = false;
                btnApply.Visible = true;
            }
        }

        protected void btnApprove_Click(object sender, EventArgs e)
        {
            try
            {
                var voterCard = ControlledModel.VoterCard.FindById(Convert.ToInt32(hdnVoterCardId.Value));
                this.LoadVoterCardValues(this.loggedInAdmin.ApproveVoterCard(voterCard));
                lblStatus.Text = "The record is Approved successfully!";

                EmailHelper.SendApproveEmail("VoterCard", voterCard.Person, ref lblStatus);
                SMSHelper.SendApproveSMS("VoterCard", voterCard.Person, ref lblStatus);
            }
            catch (ApplicationException ex)
            {
                lblStatus.Text = ex.Message;
                return;
            }
            catch (Exception ex)
            {
                Logger.ErrorLogger.Log(ex);
                lblStatus.Text = "An unexpected error occured on the application. Please contact the appropriate technical candidate for more information.";
            }
            finally
            {
                pnlAdminActions.Visible = false;
            }
        }

        protected void btnDeactivate_Click(object sender, EventArgs e)
        {
            try
            {
                var voterCard = ControlledModel.VoterCard.FindById(Convert.ToInt32(hdnVoterCardId.Value));

                if (btnDeactivate.Text == "Re-Activate")
                {
                    this.loggedInAdmin.ReActivateVoterCard(voterCard);
                    lblStatus.Text = "The record is Re-Activated successfully!";
                }
                else
                {
                    this.loggedInAdmin.DeactivateVoterCard(voterCard, txtReason.Text);
                    lblStatus.Text = "The record is Deactivated successfully!";
                }

                EmailHelper.SendDeactivationEmail("VoterCard", btnDeactivate.Text, voterCard.Person, txtReason.Text, ref lblStatus);
                SMSHelper.SendDeactivationSMS("VoterCard", btnDeactivate.Text, voterCard.Person, ref lblStatus);
            }
            catch (ApplicationException ex)
            {
                lblStatus.Text = ex.Message;
                return;
            }
            catch (Exception ex)
            {
                Logger.ErrorLogger.Log(ex);
                lblStatus.Text = "An unexpected error occured on the application. Please contact the appropriate technical candidate for more information.";
            }
            finally
            {
                pnlAdminActions.Visible = false;
            }
        }

        protected void btnDeny_Click(object sender, EventArgs e)
        {
            try
            {
                var voterCard = ControlledModel.VoterCard.FindById(Convert.ToInt32(hdnVoterCardId.Value));
                this.loggedInAdmin.DenayVoterCard(voterCard, txtReason.Text);
                lblStatus.Text = "The record is Denyed successfully!";

                EmailHelper.SendDenyNotificationEmail("VoterCard", voterCard.Person, txtReason.Text, ref lblStatus);
                SMSHelper.SendDenyNotificationSMS("VoterCard", voterCard.Person, ref lblStatus);
            }
            catch (ApplicationException ex)
            {
                lblStatus.Text = ex.Message;
                return;
            }
            catch (Exception ex)
            {
                Logger.ErrorLogger.Log(ex);
                lblStatus.Text = "An unexpected error occured on the application. Please contact the appropriate technical candidate for more information.";
            }
            finally
            {
                pnlAdminActions.Visible = false;
            }
        }

        protected void lbnViewElectricBillXerox_Click(object sender, EventArgs e)
        {
            string electricBillRelativePath = @"~\" + ControlledModel.VoterCard.FindById(Convert.ToInt32(hdnVoterCardId.Value))
                .Person.GetPermanentAddressElectricalBillFilePath()
                .Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"], String.Empty);
            Response.Redirect(electricBillRelativePath);
        }

    }
}

//Download or View PDF
//Response.Redirect("~/somePDFFile.pdf");
//OR
//string pdfPath = Server.MapPath("~/SomePDFFile.pdf");
//WebClient client = new WebClient();
//Byte[] buffer = client.DownloadData(pdfPath);
//Response.ContentType = "application/pdf";
//Response.AddHeader("content-length", buffer.Length.ToString());
//Response.BinaryWrite(buffer);